package net.Group.MembershipService;

import javax.swing.JOptionPane;

import net.jxta.credential.AuthenticationCredential;
import net.jxta.membership.Authenticator;
import net.jxta.membership.MembershipService;

import jxta.security.crypto.JxtaCrypto;
import jxta.security.exceptions.CryptoException;
import jxta.security.hash.Hash;
import jxta.security.impl.crypto.JxtaCryptoSuite;

/*
 * This class acts as a Secure Authenticator.This authenticator needs to be
 * filled correctly in order to join the peer group.Here we demonstrate the
 * usuage of the MD5 Hash algorithm of the JXTA Crypto Suite.
 * We have stored the Authetic Password(AUTHENTIC_PASSWORD) in the credential
 * Only a user who knows this password can fill the form successfully
 */
public class SecureAuthenticator implements Authenticator{
    
	private SecureMembershipService membershipService;
    private AuthenticationCredential unsubscribedCredential;    
	private String password = "";
	
	// Hex encoded MD5 hash of "password"
	private static final String AUTHENTIC_PASSWORD ="5F4DCC3B5AA765D61D8327DEB882CF99";
	
	private static final org.apache.log4j.Category LOG = 
        org.apache.log4j.Category.getInstance(SecureAuthenticator.class.getName());

    /*
     * This is the constrictor for the SecureAuthenticator
     */
    public SecureAuthenticator(SecureMembershipService membershipService,
                           AuthenticationCredential unsubscribedCredential){
        this.membershipService      = membershipService;
        this.unsubscribedCredential = unsubscribedCredential;
    }
    
    /*
     */
    public boolean  isReadyForJoin(){
    	// The AUTHENTIC_PASSWORD is the actual password to the system
    	// It is stored as a hash using the MD5 algorithm.
    	// we therefore calculate the MD5 hash of the password entered by the user
    	// and compare it with the AUTHNETIC_PASSWORD.
    	if(password == "")
    	{
    		String pass = JOptionPane.showInputDialog("Please Enter the Password of the Group:");
    		setPassword(pass);
    	}
      	try{
   		  	// Now to create the MD5 hash ,first get a suite with the MD5 Algorithm
    		JxtaCrypto crypto = new JxtaCryptoSuite(JxtaCrypto.MEMBER_MD5,
  											       null, (byte)0, (byte)0);		
   		  	// Now get the Hash Object
    		Hash hash = crypto.getJxtaHash();
    		// Get the digest length of the Hash
       		int digestLength = hash.getDigestLength();
			byte[] passwordInBytes = password.getBytes();
			// Calculate the length needed by the output byte array
			int outputLength = (password.length() < digestLength ? digestLength : password.length());
			// Create a new array to hold the output
			byte[] outputBytes = new byte[digestLength]; 
			// This is where the actual hashing is done
			hash.doFinal(passwordInBytes, 0, passwordInBytes.length, outputBytes, 0);
			// Base64 encode the result
			String finalPass = new String(jxta.security.util.Util.hexEncode(outputBytes));
			// Compare it with the AUTHENTIC_PASSWORD
			// If they match , the authenticator is ready to join
			if(finalPass.equals(AUTHENTIC_PASSWORD))
				return true;	
			else
				return false;
			
		} catch(CryptoException cryptoException){
   			LOG.error("Exception in creating MD5 Hash",cryptoException);
		}
    	return true;
    }

	/*
	 *	Setter method for password
	 */
	public void setPassword(String password){
		this.password = password;
	}

	/*
	 *	Getter method for password
	 */
	public String getPassword(){
		return password;
	}
	
	/*
     * Returns a String representing the method Name
     */
     public String getMethodName(){
        return "SecureAuthenticator";
    }

    /*
     * Returns the Authentication Credential
     */
    public AuthenticationCredential getAuthenticationCredential(){
        return unsubscribedCredential;
    }
    
    /*
     * Returns the Source Membership Service
     */
    public MembershipService  getSourceService(){
		return membershipService;
    }
}
